import 'dart:convert';

import 'package:flutter/widgets.dart';
import 'package:netease_cloud_music_api/utils/crypto.dart';
import 'package:netease_cloud_music_api/utils/enum.dart';
import 'package:netease_cloud_music_api/utils/player_request.dart';
import 'package:netease_cloud_music_api/utils/request.dart';

mixin Comment {
  /// 专辑评论
  /// [id] 专辑ID
  /// [limit] 取出数量 , 默认为 30
  /// [offset] 偏移数量 , 用于分页 , 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认 为 0
  /// [beforeTime] 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过5000条评论的时候需要用到)
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentAlbum({required int id, int? limit, int? offset, int? beforeTime}) {
    return PlayerRequest(
      url: 'https://music.163.com/weapi/v1/resource/comments/R_AL_3_${id.toString()}',
      data: {'rid': id, 'limit': limit ?? 30, 'offset': offset ?? 0, 'beforeTime': beforeTime ?? 0},
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.weapi),
    ).request();
  }

  /// 电台评论
  /// [id] 电台ID
  /// [limit] 取出数量 , 默认为 30
  /// [offset] 偏移数量 , 用于分页 , 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认 为 0
  /// [beforeTime] 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过5000条评论的时候需要用到)
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentDj({required int id, int? limit, int? offset, int? beforeTime}) {
    return PlayerRequest(
      url: 'https://music.163.com/weapi/v1/resource/comments/A_DJ_1_${id.toString()}',
      data: {'rid': id, 'limit': limit ?? 30, 'offset': offset ?? 0, 'beforeTime': beforeTime ?? 0},
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.weapi),
    ).request();
  }

  /// 获取动态评论
  /// [id] 动态ID
  /// [limit] 取出数量 , 默认为 30
  /// [offset] 偏移数量 , 用于分页 , 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认 为 0
  /// [beforeTime] 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过5000条评论的时候需要用到)
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentEvent({required int id, int? limit, int? offset, int? beforeTime}) {
    return PlayerRequest(
      url: 'https://music.163.com/weapi/v1/resource/comments/${id.toString()}',
      data: {'limit': limit ?? 30, 'offset': offset ?? 0, 'beforeTime': beforeTime ?? 0},
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.weapi),
    ).request();
  }

  /// 楼层评论
  /// [parentCommentId] 楼层评论 id
  /// [id] 资源ID
  /// [commentType] 资源类型 , 对应 song: 歌曲, mv: mv, album: 专辑, playlist: 歌单,dj: 电台, video: 视频, event: 为动态
  /// [limit] 取出数量 , 默认为 30
  /// [offset] 偏移数量 , 用于分页 , 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认 为 0
  /// [beforeTime] 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过5000条评论的时候需要用到)
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentFloor({required int id, required int parentCommentId, required CommentType commentType, int? limit, int? offset, int? beforeTime}) async {
    Map<String, dynamic> data = {
      'parentCommentId': parentCommentId,
      'time': beforeTime ?? -1,
      'limit': limit ?? 30,
      'offset': offset ?? 0,
      'threadId': _getCommentType(commentType) + id.toString(),
    };
    return PlayerRequest(
      url: 'https://music.163.com/api/resource/comment/floor/get',
      data: data,
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.weapi),
    ).request();
  }

  /// 热门评论
  /// [id] 资源ID
  /// [commentType] 资源类型 , 对应 song: 歌曲, mv: mv, album: 专辑, playlist: 歌单,dj: 电台, video: 视频, event: 为动态
  /// [limit] 取出数量 , 默认为 30
  /// [offset] 偏移数量 , 用于分页 , 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认 为 0
  /// [beforeTime] 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过5000条评论的时候需要用到)
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentHot({required int id, required CommentType commentType, int? limit, int? offset, int? beforeTime}) {
    Map<String, dynamic> data = {'rid': id, 'limit': limit ?? 30, 'offset': offset ?? 0, 'beforeTime': beforeTime ?? 0};
    return PlayerRequest(
      url: 'https://music.163.com/weapi/v1/resource/hotcomments/${_getCommentType(commentType) + id.toString()}',
      data: data,
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.weapi, cookie: 'os=pc'),
    ).request();
  }

  /// 云村热评
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentHotWallList() {
    return PlayerRequest(
      url: 'https://music.163.com/api/comment/hotwall/list/get',
      options: PlayerRequestOptions(
        method: PlayerRequestMethod.post,
        crypto: EncryptType.weapi,
      ),
    ).request();
  }

  /// 点赞与取消点赞评论
  /// [id] 资源 id, 如歌曲 id,mv id
  /// [cid] 评论 id
  /// [collect] 是否点赞, true 为点赞, false 为取消点赞
  /// [commentType] 资源类型 , 对应 song: 歌曲, mv: mv, album: 专辑, playlist: 歌单,dj: 电台, video: 视频, event: 为动态
  /// [threadId] 为动态ID, 当[commentType]为 [CommentType.event] 时 [threadId] 为必填, 否者会返回错误
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentLike({required int id, required int cid, required bool collect, required CommentType commentType, String? threadId}) {
    Map<String, dynamic> data = {
      'threadId': _getCommentType(commentType) + id.toString(),
      'commentId': cid,
    };
    if (commentType == CommentType.event) {
      data['threadId'] = threadId;
    }
    return PlayerRequest(
      url: 'https://music.163.com/weapi/v1/comment/${collect ? 'like' : 'unlike'}',
      data: data,
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.weapi, cookie: 'os=pc'),
    ).request();
  }

  /// 歌曲评论
  /// [id] 音乐 id
  /// [limit] 取出数量 , 默认为 30
  /// [offset] 偏移数量 , 用于分页 , 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认 为 0
  /// [beforeTime] 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过5000条评论的时候需要用到)
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentMusic({required int id, int? limit, int? offset, int? beforeTime}) {
    Map<String, dynamic> data = {'rid': id, 'limit': limit ?? 30, 'offset': offset ?? 0, 'beforeTime': beforeTime ?? 0};
    return PlayerRequest(
      url: 'https://music.163.com/api/v1/resource/comments/R_SO_4_${id.toString()}',
      data: data,
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.weapi, cookie: 'os=pc'),
    ).request();
  }

  /// MV评论
  /// [id] 音乐 id
  /// [limit] 取出数量 , 默认为 30
  /// [offset] 偏移数量 , 用于分页 , 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认 为 0
  /// [beforeTime] 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过5000条评论的时候需要用到)
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentMV({required int id, int? limit, int? offset, int? beforeTime}) {
    Map<String, dynamic> data = {'rid': id, 'limit': limit ?? 30, 'offset': offset ?? 0, 'beforeTime': beforeTime ?? 0};
    return PlayerRequest(
      url: 'https://music.163.com/api/v1/resource/comments/R_MV_5_${id.toString()}',
      data: data,
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.weapi, cookie: 'os=pc'),
    ).request();
  }

  /// 评论
  /// [id] 资源 id, 如歌曲 id,mv id
  /// [commentType] 资源类型 , 对应 song: 歌曲, mv: mv, album: 专辑, playlist: 歌单,dj: 电台, video: 视频, event: 为动态
  /// [page] 分页参数,每页多少条数据,默认30
  /// [sortType] 排序方式,1:按推荐排序, 2:按热度排序, 3:按时间排序
  /// [time] 当sortType为3时且页数不是第一页时需传入,值为上一条数据的time
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentNew({required int id, required CommentType commentType, int? page, int? pageSize, int? sortType, int? time, bool? showInner}) {
    Map<String, dynamic> data = Map<String, dynamic>();
    data['sortType'] = sortType == null ? 1 : (sortType > 3 ? 3 : (sortType < 1 ? 1 : sortType));
    data['pageNo'] = page ?? 1;
    data['pageSize'] = pageSize ?? 30;
    data['cursor'] = data['sortType'] == 3 ? (time ?? 0) : ((data['pageNo'] - 1) * data['pageSize']);
    data['threadId'] = _getCommentType(commentType) + id.toString();
    data['showInner'] = showInner ?? true;
    return PlayerRequest(
      url: 'https://music.163.com/eapi/v2/resource/comments',
      data: data,
      options: PlayerRequestOptions(
        method: PlayerRequestMethod.post,
        crypto: EncryptType.eapi,
        cookie: 'os=pc',
        url: '/api/v2/resource/comments',
      ),
    ).request();
  }

  /// 歌单评论
  /// [id] 音乐 id
  /// [limit] 取出数量 , 默认为 30
  /// [offset] 偏移数量 , 用于分页 , 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认 为 0
  /// [beforeTime] 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过5000条评论的时候需要用到)
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentPlaylist({required int id, int? limit, int? offset, int? beforeTime}) {
    Map<String, dynamic> data = {'rid': id, 'limit': limit ?? 30, 'offset': offset ?? 0, 'beforeTime': beforeTime ?? 0};
    return PlayerRequest(
      url: 'https://music.163.com/api/v1/resource/comments/A_PL_0_${id.toString()}',
      data: data,
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.weapi, cookie: 'os=pc'),
    ).request();
  }

  /// 视频评论
  /// [id] 音乐 id
  /// [limit] 取出数量 , 默认为 30
  /// [offset] 偏移数量 , 用于分页 , 如 :( 页数 -1)*30, 其中 30 为 limit 的值 , 默认 为 0
  /// [beforeTime] 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过5000条评论的时候需要用到)
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> commentVideo({required int id, int? limit, int? offset, int? beforeTime}) {
    Map<String, dynamic> data = {'rid': id, 'limit': limit ?? 30, 'offset': offset ?? 0, 'beforeTime': beforeTime ?? 0};
    return PlayerRequest(
      url: 'https://music.163.com/api/v1/resource/comments/R_VI_62_${id.toString()}',
      data: data,
      options: PlayerRequestOptions(method: PlayerRequestMethod.post, crypto: EncryptType.weapi, cookie: 'os=pc'),
    ).request();
  }

  /// 发送与删除评论
  /// [id] 对应资源 id
  /// [commentState] add: 为发送评论, delete: 为删除评论, reply: 为回复评论
  /// [commentType] 资源类型 , 对应 song: 歌曲, mv: mv, album: 专辑, playlist: 歌单,dj: 电台, video: 视频, event: 为动态
  /// [content] 为发送评论的内容, 当 [commentState] 为 [CommentState.add] 或 [CommentState.reply]时为必填项,
  /// 当 [commentState] 为 [CommentState.delete] 可以为空
  /// [commentId] 评论ID, 当 [commentState] 为 [CommentState.add] 或 [CommentState.delete]时 ，需要正确的评论ID,
  /// 当 [commentState] 为 [CommentState.reply] 时 [commentId] 可以为 0 或者其他数值
  /// [threadId] 当 [commentType] 为 [CommentType.event] 时, [threadId] 为必填项, 否者会返回未知错误
  /// [PlayerRequestResponse] 返回PlayerRequestResponse请求数据
  Future<PlayerRequestResponse> comments(
      {required CommentState commentState, required CommentType commentType, required int id, required String content, required int commentId, String? threadId}) async {
    Map<String, dynamic> data = {'threadId': _getCommentType(commentType) + id.toString()};
    String? t;
    if (commentType == CommentType.event) data['threadId'] = threadId;
    if (commentState == CommentState.add) {
      data['content'] = content;
      t = 'add';
    }
    if (commentState == CommentState.delete) {
      data['commentId'] = commentId;
      t = 'delete';
    }
    if (commentState == CommentState.reply) {
      data['content'] = content;
      data['commentId'] = commentId;
      t = 'reply';
    }
    print(data);

    return PlayerRequest(
      url: 'https://music.163.com/weapi/resource/comments/$t',
      data: data,
      options: PlayerRequestOptions(
        method: PlayerRequestMethod.post,
        crypto: EncryptType.weapi,
        cookie: 'os=pc',
      ),
    ).request();
  }

  String _getCommentType(CommentType commentType) {
    String _type = '';
    switch (commentType) {
      case CommentType.song:
        _type = 'R_SO_4_';
        break;
      case CommentType.mv:
        _type = 'R_MV_5_';
        break;
      case CommentType.playlist:
        _type = 'A_PL_0_';
        break;
      case CommentType.album:
        _type = 'R_AL_3_';
        break;
      case CommentType.dj:
        _type = 'A_DJ_1_';
        break;
      case CommentType.video:
        _type = 'R_VI_62_';
        break;
      case CommentType.event:
        _type = 'A_EV_2_';
        break;
    }

    return _type;
  }
}
